home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / U-Z / VideoToolBox Folder / VideoToolboxSources / PlotXY.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-23  |  3.4 KB  |  138 lines  |  [TEXT/KAHL]

  1. /* PlotXY.c
  2. Copyright © 1991 Denis G. Pelli
  3. PlotXY plots graphs, one point at a time, possibly interleaving multiple graphs. 
  4. The user keeps a PlotXYStyle structure associated with each curve, which allows
  5. interleaving of points for several curves. This is essential for online monitoring.
  6.  
  7. WARNING: I've discovered that this routine may crash if fed garbage x,y coordinates
  8. while dashing is on, e.g. extremely large numbers. I'm not sure where the problem is. 
  9. Overflows shouldn't cause crashes.
  10.  
  11. HISTORY:
  12. 90         dgp wrote it.
  13. 3/91    dgp    re-rewrote it, adding dashing and symbols, and making it re-entrant.
  14. 3/18/91    dgp    replaced floating point math by fixed point math.
  15.             made compatible with original quickdraw.
  16. 8/24/91    dgp    Made compatible with THINK C 5.0.
  17. 12/27/91 dgp Made dashing faster by measuring path length modulo the dashing period.
  18. 1/25/93 dgp removed obsolete support for THINK C 4.
  19. */
  20. #include "VideoToolbox.h"
  21.  
  22. Fixed HypotenuseF(long base,long height);
  23.  
  24. Fixed HypotenuseF(long base,long height)
  25. {
  26.     base*=base;
  27.     height*=height;
  28.     return FracSqrt(base+height)<<1;
  29. }
  30.  
  31. void PlotXY(WindowPtr window,double x,double y,PlotXYStyle *style)
  32. /*
  33. Draws line to point x,y, where window is mapped as a unit square, with origin
  34. at lower left. 
  35. */
  36. {
  37.     register PlotXYStyle *s;
  38.     register int i;
  39.     register short h,v,dh,dv;
  40.     Rect r;
  41.     WindowPtr oldPort;
  42.     PenState penState;
  43.     Pattern blackPattern={-1,-1,-1,-1,-1,-1,-1,-1};
  44.     Boolean dashOn;
  45.     int dashElements;
  46.     int dashPeriod;
  47.     int dashDebit;
  48.     int length,delta;
  49.     Fixed lengthF;
  50.     long oldColor;
  51.     int dashingPeriod;
  52.     
  53.     s=style;
  54.     GetPort(&oldPort);
  55.     SetPort(window);
  56.     BringToFront(window);
  57.     GetPenState(&penState);
  58.     oldColor=window->fgColor;
  59.     ForeColor(s->color);
  60.     PenSize(s->lineWidth,s->lineWidth);
  61.     r=window->portRect;
  62.     h=(r.right-r.left)*x;
  63.     v=(r.bottom-r.top)*(1.0-y);
  64.     
  65.     if(!s->continuing){
  66.         /* First point, just go there */
  67.         s->pathLengthF=s->dashOffset<<16;
  68.         s->h=h;
  69.         s->v=v;
  70.         MoveTo(s->h,s->v);
  71.         s->continuing=1;
  72.     }
  73.     else {
  74.         /* Not first point, start from previous point */
  75.         MoveTo(s->h,s->v);
  76.         h-=s->h;
  77.         v-=s->v;
  78.         s->h+=h;
  79.         s->v+=v;
  80.         lengthF=HypotenuseF(h,v);
  81.         length=lengthF>>16;
  82.         /* Figure out where we are in dashing sequence */
  83.         dashDebit=s->pathLengthF>>16;
  84.         dashOn=1;
  85.         dashingPeriod=0;
  86.         for(i=0;s->dash[i]>0;i++)dashingPeriod+=s->dash[i];
  87.         dashElements=i;
  88.         if(dashElements%2==1)dashingPeriod*=2;
  89.         if(dashingPeriod==0)dashingPeriod=1;    /* to avoid divide by zero */
  90.         if(dashElements==0){
  91.             Line(h,v);
  92.         }
  93.         else {
  94.             for(i=0;;i++){
  95.                 i%=dashElements;
  96.                 dashDebit-=s->dash[i];
  97.                 if(dashDebit<0){
  98.                     dashDebit+=s->dash[i];
  99.                     break;
  100.                 }
  101.                 dashOn=!dashOn;
  102.             }
  103.             /* Draw dashed line */
  104.             for(;;i++){
  105.                 i%=dashElements;
  106.                 if(length<=s->dash[i]-dashDebit){
  107.                     if(dashOn)Line(h,v);
  108.                     else Move(h,v);
  109.                     dashDebit+=length;
  110.                     break;
  111.                 }
  112.                 delta=s->dash[i]-dashDebit;
  113.                 dh=((long)h*delta+length/2)/length;
  114.                 dv=((long)v*delta+length/2)/length;
  115.                 if(dashOn)Line(dh,dv);
  116.                 else Move(dh,dv);
  117.                 h-=dh;
  118.                 v-=dv;
  119.                 length-=delta;
  120.                 dashDebit=0;
  121.                 dashOn=!dashOn;
  122.             }
  123.         }
  124.         lengthF%=(long)dashingPeriod<<16;        /* reduce mod period to avoid overflow */
  125.         s->pathLengthF+=lengthF;
  126.         s->pathLengthF%=(long)dashingPeriod<<16;/* reduce mod period for speed */
  127.     }
  128.     
  129.     /* Draw symbol */
  130.     SetRect(&r,0,0,s->symbolWidth,s->symbolWidth);
  131.     OffsetRect(&r,-r.right/2,-r.bottom/2);
  132.     OffsetRect(&r,s->h,s->v);
  133.     FillOval(&r,blackPattern);
  134.     ForeColor(oldColor);
  135.     SetPenState(&penState);
  136.     SetPort(oldPort);
  137. }
  138.